home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 15 / macformat_15.iso / Shareware Internet / Desarrolladores / gray image 2.1 / read_pgm.cc < prev    next >
Text File  |  1995-05-30  |  5KB  |  157 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /*
  3.  ************************************************************************
  4.  *
  5.  *               Grayscale Image
  6.  *
  7.  *         Read an image from a Portable GrayMap (pgm) file
  8.  * 
  9.  * The program reads a "binary" (RAWBITS) pgm file of the following format
  10.  *   - A "magic number" for identifying the file type.  A pgm
  11.  *     file's RAWBITS magic number is the two characters "P5".
  12.  *   - Whitespace (blanks, TABs, CRs, LFs).
  13.  *   - A width, formatted as ASCII characters in decimal.
  14.  *   - Whitespace.
  15.  *   - A height, again in ASCII decimal.
  16.  *   - Whitespace.
  17.  *   - The maximum gray value, again in ASCII decimal. For RAWBITS pgm file
  18.  *       the maximum grayscale value cannot exceed 255.
  19.  *   - A _single_ character of whitespace (typically a newline).
  20.  *   - Width * height gray values, each as plain bytes, between
  21.  *     0 and the specified maximum value, stored consecutivly, 
  22.  *     starting at the top-left corner of the graymap, proceding in normal
  23.  *     English reading order. 
  24.  *     A value of 0 means black, and the maximum value means white.
  25.  *
  26.  * For more detail, see documentation on PBMPLUS package (specifically,
  27.  * pgm(5)).
  28.  *
  29.  * $Id: read_pgm.cc,v 2.0 1995/03/06 20:57:48 oleg Exp oleg $
  30.  *
  31.  ************************************************************************
  32.  */
  33.  
  34. #include "image.h"
  35. #include "endian_io.h"
  36. #include <iostream.h>
  37. #include <ctype.h>
  38.  
  39. /*
  40.  *------------------------------------------------------------------------
  41.  *               Class PGMFile
  42.  *     designed to contain the control info about the image
  43.  *        as defined in the Portable GrayMap file 
  44.  */
  45.  
  46. class PGMFile : public PixelPrimAction
  47. {
  48.   EndianIn& inf;            // stream to read from
  49.   card pixmap_width;            // Dimensions of the graymap
  50.   card pixmap_height;
  51.   card max_gray_value;            // Maximum value of a graymap pixel
  52.   card pixmap_depth;            // ceil(log2(max_gray_value))
  53.  
  54.   void operation(GRAY& pixel);
  55.  
  56. public:
  57.   PGMFile(EndianIn& _inf);
  58.   void info(void) const;        // Dump the header information
  59.   const char * q_name(void) const    { return ""; }
  60.   card q_nrows(void) const        { return pixmap_height; }
  61.   card q_ncols(void) const        { return pixmap_width; }
  62.   card q_depth(void) const        { return pixmap_depth; }
  63. };
  64.  
  65. /*
  66.  *------------------------------------------------------------------------
  67.  *            Construct the PGMFile
  68.  *           by reading the header of a PGM file
  69.  */
  70.  
  71. PGMFile::PGMFile(EndianIn& file) : inf(file)
  72. {
  73.   const char * magic_str = "P5";
  74.   char read_magic_str[3];
  75.   read_magic_str[0] = inf.read_byte("Reading magic string");
  76.   read_magic_str[1] = inf.read_byte("Reading magic string");
  77.   read_magic_str[2] = '\0';
  78.   if( strcmp(read_magic_str,magic_str) != 0 )
  79.     _error("Read magic string '%s' is not what's expected '%s':"
  80.            "it's not a Portable GrayMap (PGM) file",read_magic_str,magic_str);
  81.   
  82.   if( !(inf >> pixmap_width) )
  83.     _error("Failed to read the number of columns (graymap width)");
  84.    
  85.   if( !(inf >> pixmap_height) )
  86.     _error("Failed to read the number of rows (graymap height)");
  87.     
  88.   
  89.   if( !(inf >> max_gray_value) )
  90.     _error("Failed to read the maximum gray value in the map");
  91.  
  92.   char c;
  93.   assert( inf.get(c) );
  94.   assure( isspace(c), "Failed to get a single space after the header");
  95.  
  96.   assert( pixmap_width > 0 && pixmap_height > 0 && max_gray_value > 0);
  97.  
  98.   if( max_gray_value > 255 )
  99.     _error("Can't handle the graymap with the maximum gray value, %d, "
  100.        "greater than 255",max_gray_value);
  101.    
  102.   {
  103.     int t;
  104.     for(pixmap_depth=0,t=1; t < max_gray_value+1; pixmap_depth++, t *= 2)
  105.       ;
  106.   }
  107. }
  108.  
  109. /*
  110.  *------------------------------------------------------------------------
  111.  *    Print out all the control information pertaining to the
  112.  *             X Window Image read
  113.  */
  114.  
  115. void PGMFile::info(void) const
  116. {
  117.   cout << "\n\n=====>The following Portable GrayMap has been read";
  118.   cout << "\nPixmap depth:   " << pixmap_depth;
  119.   cout << "\nPixmap width:   " << pixmap_width;
  120.   cout << "\nPixmap height:  " << pixmap_height;
  121.   cout << "\nMax gray value: " << max_gray_value;
  122.  
  123.   cout << "\n-----End of PGM information\n";
  124. }
  125.  
  126. /*
  127.  *------------------------------------------------------------------------
  128.  *               Read a pixelmap
  129.  */
  130.  
  131. void PGMFile::operation(GRAY& pixel)
  132. {
  133.   pixel = inf.read_byte("reading the pixel matrix");
  134. }
  135.  
  136. /*
  137.  *========================================================================
  138.  *             Root module - actual IMAGE constructor
  139.  */
  140.  
  141. void IMAGE::read_pgm(EndianIn& file, const bool print_header_info)
  142. {
  143.   message("Reading the Portable GrayMap (PGM)\n");
  144.   
  145.   PGMFile pgmfile(file);
  146.  
  147.   if( print_header_info )
  148.     pgmfile.info();
  149.  
  150.   allocate(pgmfile.q_nrows(),pgmfile.q_ncols(),pgmfile.q_depth());
  151.  
  152.   apply(pgmfile);
  153.  
  154.   cout << "\n" << ncols << "x" << nrows << "x" << bits_per_pixel << " image '"
  155.          << name << "' has been read" << endl;
  156. }
  157.